﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NPOI.SS.UserModel;

namespace YJKRevitBase.ExcelUtility.ExcelORM
{
	internal class TypeInfo
	{
		internal TypeInfo(Type useType, ClassAttribute useClassAttribute, Dictionary<PropertyInfo, PropertyAttribute> inputPropertyMap)
		{
			this.m_thisType = useType;
			this.m_useClassAttribute = useClassAttribute;
			foreach (KeyValuePair<PropertyInfo, PropertyAttribute> keyValuePair in inputPropertyMap)
			{
				this.m_lstPropertyInfos.Add(new TypePropertyInfo(keyValuePair.Key, keyValuePair.Value));
			}
		}

		internal List<object> ReadWorkBook(IWorkbook input)
		{
			this.PrepareDataForRead(input);
			int count = this.m_lstPropertyInfos.Count;
			string[] array = new string[count];
			string[] array2 = new string[count];
			List<object> list = new List<object>();
			object lastValue = null;
			int nowGetNoneLstPropertyValue = 0;
			int num = 0;
			bool flag = false;
			for (int i = this.m_dataStartRowNumber; i <= this.m_useSheet.LastRowNum; i++)
			{
				nowGetNoneLstPropertyValue = 0;
				flag = false;
				num = 0;
				IRow row = this.m_useSheet.GetRow(i);
				if (row != null)
				{
					this.ReadOneRow(count, array, array2, ref num, ref nowGetNoneLstPropertyValue, ref flag, row);
					if (!flag || 1 != num)
					{
						try
						{
							if (count != (from n in array
							where n == null
							select n).Count<string>())
							{
								lastValue = this.SetValue(count, array, array2, list, lastValue, nowGetNoneLstPropertyValue);
							}
						}
						catch (Exception)
						{
						}
					}
				}
			}
			return list;
		}

		internal void WriteToWorkBook(IWorkbook input, List<object> lstInputValues)
		{
			this.PrepareDataForeWrite(input);
			int num = 1;
			Dictionary<int, IRow> useRowDic = new Dictionary<int, IRow>();
			foreach (object oneValue in lstInputValues)
			{
				int num2 = 0;
				num2 = this.WriteOneValue(num, num2, useRowDic, oneValue);
				num += num2;
				num++;
			}
		}

		private int WriteOneValue(int nowUseRowIndex, int appendIndexNumber, Dictionary<int, IRow> useRowDic, object oneValue)
		{
			foreach (TypePropertyInfo typePropertyInfo in this.m_lstPropertyInfos)
			{
				List<string> value = typePropertyInfo.GetValue(oneValue);
				appendIndexNumber = System.Math.Max(appendIndexNumber, value.Count - 1);
				int num = nowUseRowIndex;
				foreach (string text in value)
				{
					if (!useRowDic.ContainsKey(num))
					{
						useRowDic.Add(num, this.m_useSheet.CreateRow(num));
					}
					ICell cell = useRowDic[num].CreateCell(typePropertyInfo.UseColumnIndex);
					cell.SetCellType(CellType.String);
					cell.SetCellValue(text.ToString());
					num++;
				}
			}
			return appendIndexNumber;
		}

		private void PrepareDataForeWrite(IWorkbook inputWorkbook)
		{
			this.m_useSheet = null;
			if (!string.IsNullOrEmpty(this.m_useClassAttribute.SheetName))
			{
				this.m_useSheet = inputWorkbook.CreateSheet(this.m_useClassAttribute.SheetName);
			}
			else
			{
				this.m_useSheet = inputWorkbook.CreateSheet();
			}
			IRow inputRow = this.m_useSheet.CreateRow(0);
			int num = 0;
			HashSet<int> hashSet = new HashSet<int>();
			foreach (TypePropertyInfo typePropertyInfo in this.m_lstPropertyInfos)
			{
				typePropertyInfo.PrepareDataForWrite(inputRow, ref num, ref hashSet);
			}
		}

		private void PrepareDataForRead(IWorkbook inputWorkbook)
		{
			this.m_useSheet = null;
			this.m_dataStartRowNumber = 0;
			if (0 <= this.m_useClassAttribute.SheetIndex)
			{
				this.m_useSheet = inputWorkbook.GetSheetAt(this.m_useClassAttribute.SheetIndex);
			}
			else
			{
				this.m_useSheet = inputWorkbook.GetSheet(this.m_useClassAttribute.SheetName);
			}
			int num = 0;
			int val = 0;
			foreach (TypePropertyInfo typePropertyInfo in this.m_lstPropertyInfos)
			{
				typePropertyInfo.PrepareDataForRead(this.m_useSheet, out val);
				num = System.Math.Max(num, val);
			}
			this.m_dataStartRowNumber = ((this.m_useClassAttribute.RealUseDataStartRowIndex < 0) ? num : this.m_useClassAttribute.RealUseDataStartRowIndex);
		}

		private object SetValue(int useLength, string[] useValues, string[] readedRowValue, List<object> returnValues, object lastValue, int nowGetNoneLstPropertyValue)
		{
			bool flag = false;
			object obj;
			if (nowGetNoneLstPropertyValue > 0 || lastValue == null)
			{
				obj = Activator.CreateInstance(this.m_thisType);
				returnValues.Add(obj);
				flag = true;
			}
			else
			{
				obj = lastValue;
			}
			for (int i = 0; i < useLength; i++)
			{
				string text;
				if (flag && this.m_lstPropertyInfos[i].IfIsLstType)
				{
					text = readedRowValue[i];
					useValues[i] = text;
				}
				else
				{
					text = useValues[i];
				}
				if (text != null)
				{
					this.m_lstPropertyInfos[i].SetValue(obj, text);
				}
			}
			lastValue = obj;
			return lastValue;
		}

		private void ReadOneRow(int useLength, string[] useValues, string[] readedValues, ref int readedValue, ref int nowGetNoneLstPropertyValue, ref bool continueTag, IRow useRow)
		{
			for (int i = 0; i < useLength; i++)
			{
				TypePropertyInfo typePropertyInfo = this.m_lstPropertyInfos[i];
				readedValues[i] = null;
				if (!typePropertyInfo.UseLastValueWhenWhiteSpace && !typePropertyInfo.ChangeToNextRowWhenReadValue)
				{
					useValues[i] = null;
				}
				ICell cell = useRow.GetCell(typePropertyInfo.UseColumnIndex);
				if (cell != null && !string.IsNullOrWhiteSpace(cell.ToString()))
				{
					if (!typePropertyInfo.IfIsLstType)
					{
						nowGetNoneLstPropertyValue++;
					}
					useValues[i] = cell.ToString();
					readedValues[i] = cell.ToString();
					if (typePropertyInfo.ChangeToNextRowWhenReadValue)
					{
						continueTag = true;
					}
					readedValue++;
				}
			}
		}

		private Type m_thisType;

		private ClassAttribute m_useClassAttribute;

		private int m_dataStartRowNumber;

		private List<TypePropertyInfo> m_lstPropertyInfos = new List<TypePropertyInfo>();

		private ISheet m_useSheet;
	}
}
